//! # API网关集成测试
//!
//! 验证整个middleware pipeline的工作流程，确保各个中间件能够协同工作。

use crate::core::*;
use crate::router::{Route, Router, RouterMiddleware};
use crate::filter::{LoggingMiddleware};

use axum::http::{Method, Uri, StatusCode};
use std::collections::HashMap;
use std::sync::Arc;
use std::time::{Duration, SystemTime};

// ==================== 工具函数 ====================

/// 创建测试用的网关请求
fn create_test_request(method: Method, path: &str) -> GatewayRequest {
    let uri: Uri = path.parse().unwrap_or_else(|_| Uri::from_static("/"));
    let mut request = GatewayRequest::new(method, uri);
    request.path = path.to_string();
    request.set_client_ip("192.168.1.100".to_string());
    request
}

/// 创建测试用的网关上下文
fn create_test_context() -> Arc<GatewayContext> {
    Arc::new(GatewayContext {
        request_id: format!("test-{}", SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_nanos()),
        auth_info: None,
        rate_limit_info: None,
        route_info: None,
        attributes: HashMap::new(),
        start_time: SystemTime::now(),
    })
}

// ==================== 集成测试用例 ====================

#[cfg(test)]
mod integration_tests {
    use super::*;

    #[tokio::test]
    async fn test_router_middleware_integration() {
        // 测试路由中间件的集成
        let route1 = Route::new("/api/users", "user-service");
        let route2 = Route::new("/api/orders", "order-service");
        
        let router = Router::new()
            .add_route(route1)
            .add_route(route2);
        
        let router_middleware = RouterMiddleware::new(router);
        
        // 测试成功的路由
        let request = create_test_request(Method::GET, "/api/users/profile");
        let context = create_test_context();
        
        let result = router_middleware.before_request(request, context).await;
        assert!(result.is_ok(), "路由中间件应该成功处理请求");
        
        let routed_request = result.unwrap();
        assert_eq!(routed_request.target_service, Some("user-service".to_string()));
        assert_eq!(routed_request.path, "/profile");
    }

    #[tokio::test]
    async fn test_logging_middleware_integration() {
        // 测试日志中间件的集成
        let logging_middleware = LoggingMiddleware::new(log::Level::Info);
        
        let request = create_test_request(Method::POST, "/api/orders");
        let context = create_test_context();
        
        // 前置处理
        let result = logging_middleware.before_request(request, context.clone()).await;
        assert!(result.is_ok(), "日志中间件应该总是允许请求通过");
        
        // 后置处理
        let response = GatewayResponse::new(StatusCode::OK);
        let result = logging_middleware.after_response(response, context).await;
        assert!(result.is_ok(), "日志中间件应该总是允许响应通过");
    }

    #[tokio::test]
    async fn test_middleware_priority_ordering() {
        // 测试中间件优先级排序
        let logging_middleware = LoggingMiddleware::new(log::Level::Info);
        let route = Route::new("/api", "test-service");
        let router = Router::new().add_route(route);
        let router_middleware = RouterMiddleware::new(router);
        
        // 验证优先级：路由(1) < 日志(1000)
        assert!(router_middleware.priority() < logging_middleware.priority());
        
        // 验证中间件名称
        assert_eq!(router_middleware.name(), "Router");
        assert_eq!(logging_middleware.name(), "LoggingMiddleware");
    }

    #[tokio::test]
    async fn test_context_propagation() {
        // 测试上下文信息在中间件间的传递
        let request_id = "context-test-456";
        let start_time = SystemTime::now();
        
        let context = Arc::new(GatewayContext {
            request_id: request_id.to_string(),
            auth_info: None,
            rate_limit_info: None,
            route_info: None,
            attributes: HashMap::new(),
            start_time,
        });
        
        // 验证上下文信息保持不变
        assert_eq!(context.request_id, request_id);
        assert_eq!(context.start_time, start_time);
        
        let request = create_test_request(Method::GET, "/api/test");
        
        // 路由中间件
        let route = Route::new("/api", "test-service");
        let router = Router::new().add_route(route);
        let router_middleware = RouterMiddleware::new(router);
        
        let result = router_middleware.before_request(request, context.clone()).await;
        assert!(result.is_ok());
        
        // 验证上下文信息没有被破坏
        assert_eq!(context.request_id, request_id);
        assert_eq!(context.start_time, start_time);
    }

    #[tokio::test]
    async fn test_error_propagation() {
        // 测试错误在中间件链中的传播
        let request = create_test_request(Method::GET, "/unknown/path");
        let context = create_test_context();
        
        // 创建一个只有特定路由的路由器
        let route = Route::new("/api/users", "user-service");
        let router = Router::new().add_route(route);
        let router_middleware = RouterMiddleware::new(router);
        
        // 路由中间件应该返回路由错误
        let result = router_middleware.before_request(request, context).await;
        assert!(result.is_err(), "未知路径应该导致路由错误");
        
        let error = result.unwrap_err();
        assert!(matches!(error, GatewayError::Routing { .. }));
    }

    #[tokio::test]
    async fn test_performance_monitoring() {
        // 测试性能监控功能
        let start_time = std::time::Instant::now();
        
        // 模拟处理一个请求的完整流程
        let request = create_test_request(Method::GET, "/api/users");
        let context = create_test_context();
        
        // 路由中间件处理
        let route = Route::new("/api/users", "user-service");
        let router = Router::new().add_route(route);
        let router_middleware = RouterMiddleware::new(router);
        
        let result = router_middleware.before_request(request, context.clone()).await;
        assert!(result.is_ok());
        
        // 日志中间件处理
        let logging_middleware = LoggingMiddleware::new(log::Level::Info);
        let response = GatewayResponse::new(StatusCode::OK);
        let result = logging_middleware.after_response(response, context).await;
        assert!(result.is_ok());
        
        // 记录处理时间
        let processing_time = start_time.elapsed();
        
        // 验证处理时间在合理范围内（应该很快）
        assert!(processing_time < Duration::from_millis(100), "中间件处理时间应该很快: {:?}", processing_time);
        
        println!("集成测试处理时间: {:?}", processing_time);
    }
}